package com.mew.slots.core.game.kbwsj.room;


import cn.hutool.core.util.RandomUtil;
import com.mew.common.util.GameUtil;
import com.mew.slots.core.common.game.BaseRoom;
import com.mew.slots.core.common.game.vo.BasePlayMsgs;
import com.mew.slots.core.common.roller.xml.BaseXml;
import com.mew.slots.core.game.kbwsj.roller.KbwsjIli;
import com.mew.slots.core.game.kbwsj.roller.KbwsjXml;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.IntFunction;
import java.util.stream.Collectors;

public class KbwsjRoom extends BaseRoom {

    public static int _COIN = 11;

    public static int _VAMPIRE = 6;//_WILD不允许替换
    public static int _SCATTER = 8;//_WILD不允许替换
    public static int _TURNTABLE = 9;//_WILD不允许替换
    public static int _Free_1 = 10;//_WILD不允许替换

    public static int[] jpWeights = {100,20,5,1};

    //99  翻倍 ，100  jp
    public static int[] coins = {1,2,5,8,10,99,100};
    public static int[] turntable = {1 , 2  ,3  ,5 , 8 ,18};
    public static int[] turntableWeights = {550,250,50,15,5,1};

    public static int[] vampireSeat = {3,7,12,18,24,31};
    //97 5免费,98 w*2,   99  50w ,100 100C
    public static int[] vampireBox1 = {2,3,6,8,10,15,97,98};
    public static int[] vampireBox2 = {3,6,8,10,15,97,98,99};
    public static int[] vampireBox3 = {6,8,10,15,97,98,99,100};
    //第几大关
    public int point;

    public ArrayList<ArrayList<Integer>> colLines;

    public KbwsjRoom(){
        res = new KbwsjPlayMsgs();
        row = 3;
        col = 5;
        _WILD = 7;
        spes = new ArrayList<Integer>(){{
            add(8);
            add(9);
            add(10);
            add(11);
            add(12);
            add(13);
            add(14);
            add(15);
            add(16);
            add(17);
        }};

        //眼 0 ， 魂 1，头  2， 蜘  3， 绿  4，  女  5 ，男  6 ， W 7, S城堡  8 ,转盘  9 ，免费+1  10 ，  硬币11+

        rate = new int[][]{
                {0, 0,  4,   10, 20},
                {0, 0,  4,   10, 20},
                {0, 0,  4,   10, 20},
                {0, 0,  4,   10, 20},
                {0, 0,  6,   12, 30},
                {0, 0,  8,   16, 40},
                {0, 0,  10,   20, 80},
                {0, 0,  10,   20, 80},
                {0, 0,  0,   0, 0},
                {0, 0,  0,   0, 0},
                {0, 0,  0,   0, 0},
                {0, 0,  0,   0, 0},
        };

         alllines = new int[][]{
                 {0,1,2,3,4},
                 {5,6,7,8,9},
                 {10,11,12,13,14},
                 {0,6,7,8,9},
                 {0,11,12,13,14},
                 {5,1,2,3,4},
                 {5,11,12,13,14},
                 {10,1,2,3,4},
                 {10,6,7,8,9},
                 {0,6,2,3,4},
                 {0,6,12,13,14},
                 {0,11,2,3,4},
                 {0,11,7,8,9},
                 {5,6,2,3,4},
                 {5,6,12,13,14},
                 {10,11,2,3,4},
                 {10,11,7,8,9},
                 {0,1,7,8,9},
                 {0,1,12,13,14},
                 {0,1,2,8,9},


                 {0,1,2,3,4},
                 {5,6,7,8,9},
                 {10,11,12,13,14},
                 {15,16,17,18,19},
                 {20,21,22,23,24},
                 {25,26,27,28,29},
                 {0,6,2,3,4},
                 {0,6,7,8,9},
                 {0,6,12,13,14},
                 {0,6,17,18,19},
                 {0,6,22,23,24},
                 {0,6,27,28,29},
                 {0,11,2,3,4},
                 {0,11,7,8,9},
                 {0,11,12,13,14},
                 {0,11,17,18,19},
                 {0,11,22,23,24},
                 {0,11,27,28,29},
                 {0,16,2,3,4},
                 {0,16,7,8,9},
                 {0,16,12,13,14},
                 {0,16,17,18,19},
                 {0,16,22,23,24},
                 {0,16,27,28,29},
                 {0,21,2,3,4},
                 {0,21,7,8,9},
                 {0,21,12,13,14},
                 {0,21,17,18,19},
                 {0,21,22,23,24},
                 {0,21,27,28,29},
                 {0,26,2,3,4},
                 {0,26,7,8,9},
                 {0,26,12,13,14},
                 {0,26,17,18,19},
                 {0,26,22,23,24},
                 {0,26,27,28,29},
                 {20,26,2,3,4},
                 {20,26,7,8,9},
                 {20,26,12,13,14},
                 {20,26,17,18,19},
                 {20,26,22,23,24},
                 {20,26,27,28,29},
                 {0,6,12,18,24},
                 {5,11,17,23,29},
                 {0,1,7,13,19},
                 {0,1,12,18,24},
                 {0,1,12,18,29},
                 {10,16,2,3,4},
                 {10,16,7,8,9},
                 {10,16,12,13,14}

         };
    }

    @Override
    public void init(Integer rollerID, BaseXml xml, Boolean free, long bet0, Integer controlType) {

        this.rollerXml = xml;

        if (free){
            row = 6;
            this.lines = Arrays.stream(alllines).skip(20).limit(50).toArray(new IntFunction<int[][]>() {
                @Override
                public int[][] apply(int value) {
                    return new int[value][];
                }
            });
        }else {
            this.lines = Arrays.stream(alllines).limit(20).toArray(new IntFunction<int[][]>() {
                @Override
                public int[][] apply(int value) {
                    return new int[value][];
                }
            });
        }

        //在第几大关
        for (int i = 0; i < vampireSeat.length; i++) {
            if (((KbwsjPlayMsgs)res).vampireSeat<=vampireSeat[i]){
                point = i;
                break;
            }
        }

        //扣下注
        this.res.bet = bet0;

        this.res.allwin = 0;
        //线数
        this.res.setLine(20);
        //开始主游戏
        this.free = free;
        this.rollerID = rollerID;
        this.controlType = controlType;

    }

    @Override
    public void freeBouns(){

        int fsdb = fsdb(_SCATTER);

        if (fsdb>2){
            res.free = 1;
            res.freeNumber = 8;
            res.multiple+= 20;
            ((KbwsjPlayMsgs)res).freeType=0;
        }

        if (free){
            //免费加1
            int free1 = fsdb(_Free_1);
            if (free1>0){
                res.free = 1;
                res.freeNumber = free1;
            }

        }else if (fsdb<3){
            //吸血鬼
            int vampire = fsdb(_VAMPIRE);


            ((KbwsjPlayMsgs)res).vampireAdd = vampire;
            ((KbwsjPlayMsgs)res).vampire+=vampire;
            if (((KbwsjPlayMsgs)res).vampire>=100){
                ((KbwsjPlayMsgs)res).vampire = 0;
                ((KbwsjPlayMsgs)res).isVampire = 1;
                ((KbwsjPlayMsgs)res).vampireSeat += 1;

                if (((KbwsjPlayMsgs)res).vampireSeat>31){
                    ((KbwsjPlayMsgs)res).vampireSeat = 1;
                    ((KbwsjPlayMsgs)res).task =  new int[][]{{0,0},{0,0},{0,0,0},{0,0,0},{0,0,0,0},{0,0,0,0}};

                    ((KbwsjPlayMsgs)res).reStart =  true;
                }

                //在第几大关
                for (int i = 0; i < vampireSeat.length; i++) {
                    if (((KbwsjPlayMsgs)res).vampireSeat<=vampireSeat[i]){
                        point = i;
                        break;
                    }
                }

                //在不在检查点
                List<Integer> vampireSeatList = Arrays.stream(vampireSeat).boxed().collect(Collectors.toList());
                int vampireIdx = vampireSeatList.indexOf(((KbwsjPlayMsgs)res).vampireSeat);

                if (vampireIdx==-1){
                    //不在检查点上  开个箱子
                    openBox(vampire, point);
                }else {
                    //结算关
                    ((KbwsjPlayMsgs)res).freeType = 1;
                    res.free = 1;
                    res.freeNumber = 8 + (((KbwsjPlayMsgs)res).task[point][0]==1?5:0);
                }
            }

        }

        res.bouns = -1;

        for (int i = 0; i < colLines.size(); i++) {
            ArrayList<Integer> colIcons = colLines.get(i);
            int num = 0;
            for (int j = 0; j < colIcons.size(); j++) {
                if (num==0&&colIcons.get(j)==_TURNTABLE){
                    num=1;
                }else if (num>0&&colIcons.get(j-1)==_TURNTABLE&&colIcons.get(j)==_TURNTABLE){
                    num++;
                }else {
                    num=0;
                }

                if (num>2){
                    //爆转盘
                    res.bouns = i;
                    break;
                }

            }

            if (res.bouns>-1){
                break;
            }
        }

        if (res.bouns>-1){
            //爆分
            int weight = GameUtil.weights(turntableWeights);
            if (((KbwsjPlayMsgs)res).coinCol[res.bouns][2]>0){
                res.jp = GameUtil.weights(jpWeights)+1;
            }

            //数值超int 不背锅 老卢说的
            res.bounswin = (long) (((KbwsjPlayMsgs)res).coinCol[res.bouns][0]* res.bet*(res.line/10)*(((KbwsjPlayMsgs)res).coinCol[res.bouns][1]+1))*turntable[weight];
            ((KbwsjPlayMsgs)res).coinCol[res.bouns][0] = 1;
            ((KbwsjPlayMsgs)res).coinCol[res.bouns][1] = 0;
            ((KbwsjPlayMsgs)res).coinCol[res.bouns][2] = 0;

            ((KbwsjPlayMsgs)res).turntable = turntable[weight];
        }


    }

    private void openBox(int vampire,int seat) {
        List<Integer> box = null;
        if (point < 2){
            //前两关
            box = Arrays.stream(vampireBox1).boxed().collect(Collectors.toList());
        }else if (point < 4){
            //前3关
            box = Arrays.stream(vampireBox2).boxed().collect(Collectors.toList());
        }else {
            //前4关
            box = Arrays.stream(vampireBox3).boxed().collect(Collectors.toList());
        }
        Collections.shuffle(box);
        Arrays.stream(((KbwsjPlayMsgs) res).task).forEach(ii-> {
            System.out.println(Arrays.stream(ii).boxed().collect(Collectors.toList()));
        });
        //算分
        for (int i = 0; i < 3; i++) {
            Integer bo = box.get(i);
            if (bo<90){
                ((KbwsjPlayMsgs)res).vampireWin += bo * res.line;
            }else {
                ((KbwsjPlayMsgs)res).task[point][bo-97] = 1;
            }
        }

        res.allwin += ((KbwsjPlayMsgs)res).vampireWin;
        ((KbwsjPlayMsgs)res).vampireBox = box.stream().mapToInt(Integer::intValue).toArray();
    }

    @Override
    public void getLinesXml() {

        ArrayList<int[]>  lines = getLines(free ? 1 : 0, rollerID);

        ((KbwsjPlayMsgs)res).allSlots = lines;

        endSlots = lines.get(lines.size()-1);

        res.endSlots = endSlots.clone();

    }


    /**
     *  每条线算分
     */
    @Override
    public void checkaward(){

        //特殊免费 w*2
        boolean w2 = free&&((KbwsjPlayMsgs)res).freeType==1&&((KbwsjPlayMsgs)res).task[point][1]==1;
        ((KbwsjPlayMsgs)res).w2 = w2?1:0;
        boolean haveW = false;
        int[] rl;
        int type;
        int num;

        for (int j = 0;j< iconLines.length;j++) {

            BasePlayMsgs.LineResult bgo = new BasePlayMsgs.LineResult();
            bgo.lineNum = j;
            rl = iconLines[j].clone();
            type = rl[0];
            num = 0;
            //不为特殊图标
            if (spes.contains(type)){
                continue;
            }

            //确定类型
            for(int i=0;i<rl.length;i++){
                if(rl[i]!=_WILD){
                    type=rl[i];
                    break;
                }
            }

            for (int i = 0; i < rl.length; i++) {
                if (type==rl[i]) {
                    num++;
                }else if (rl[i] == _WILD){
                    num++;
                    haveW = true;
                }else {
                    break;
                }
            }

            if (num>1){
                Integer rate0 = rate[type][num - 1] * (w2&&haveW?2:1);
                if (rate0 > 0) {
                    bgo.mult = rate0;
                    bgo.type = type;
                    bgo.num = num;
                    bgo.uvIdx = Arrays.stream(lines[j]).limit(num).toArray();
                    res.lines.add(bgo);
                }
            }

        }

        for(BasePlayMsgs.LineResult x:res.lines)
        {
            res.multiple += x.mult;
        }

    }

    //往下掉
    public ArrayList<int[]> iconDown(ArrayList<ArrayList<Integer>> cols){

        ArrayList<int[]> allSlots = new ArrayList<>();

        //金币篮子
        int[][] coinCol = ((KbwsjPlayMsgs)res).coinCol;
        long sum = cols.stream().mapToLong(i -> i.stream().filter(s->s>-1).count()).sum();
        if (sum>col*row){
            do{
                //截最下面几个发给前端
                int[] ints = ((KbwsjXml)rollerXml).col2row(cols);

                int[] slots = Arrays.stream(ints).skip(ints.length - row * col).toArray();
                allSlots.add(slots);

                for (int i = 0; i < cols.size(); i++) {
                    ArrayList<Integer> col = cols.get(i);

                    //只循环3次
                    int colIdx = 0;
                    for (int j = 0; j < row; j++) {
                        if (col.get(colIdx)>=_COIN){
                            Integer icon = col.get(colIdx);
                            //是金币
                            int coin = coins[icon - _COIN];
                            if(coin==99||coin==100){

                                if (coin==99 && coinCol[i][1]!=1){
                                    coinCol[i][1] = 1;
                                }else if (coin==100 && coinCol[i][2]!=1){
                                    coinCol[i][2] = 1;
                                }else {
                                    slots[i+(row-j-1)*this.col] = _COIN;
                                    coinCol[i][0] += coins[0];
                                }

                            }else if (coin==100){
                                coinCol[i][2] = 1;
                            }else {
                                coinCol[i][0] += coin;
                            }
                            col.remove(colIdx);
                        }else {
                            colIdx++;
                        }
                    }
                }
                sum = cols.stream().mapToLong(i -> i.stream().filter(s->s>-1).count()).sum();

            } while (sum>col*row);

        }

        //最后一张
        int[] ints = ((KbwsjXml)rollerXml).col2row(cols);
        int[] slots = Arrays.stream(ints).skip(ints.length - row * col).toArray();
        allSlots.add(slots);

        ((KbwsjPlayMsgs)res).coinCol = coinCol;
        return allSlots;
    }

    public ArrayList<int[]> getLines(int path, int rollerID) {
        if (controlType>0){
            int[] i1 = new int[row];
            int[] i2 = new int[row];
            int[] i3 = new int[row];
            int[] i4 = new int[row];
            int[] i5 = new int[row];

            colLines = new ArrayList<ArrayList<Integer>>(){{
                add((ArrayList<Integer>) Arrays.stream(i1).boxed().collect(Collectors.toList()));
                add((ArrayList<Integer>) Arrays.stream(i2).boxed().collect(Collectors.toList()));
                add((ArrayList<Integer>) Arrays.stream(i3).boxed().collect(Collectors.toList()));
                add((ArrayList<Integer>) Arrays.stream(i4).boxed().collect(Collectors.toList()));
                add((ArrayList<Integer>) Arrays.stream(i5).boxed().collect(Collectors.toList()));
            }};

            if (controlType==1){

                int[] bigwin = bigwin();
                int bigRow = bigwin.length / 5;
                for (int i = 0; i < col; i++) {
                    //五列
                    for (int j = 0; j < bigRow; j++) {
                        //bigRow行
                        colLines.get(i).set(bigRow-1-j,bigwin[i+j*col]);
                    }
                }

            }else if (controlType==2){
                colLines.get(1).set(0,_SCATTER);
                colLines.get(2).set(0,_SCATTER);
                colLines.get(3).set(0,_SCATTER);
            }else if (controlType==3){
                ((KbwsjPlayMsgs)res).vampire = 95;
            }else {
                colLines.get(2).set(0,_TURNTABLE);
                colLines.get(2).set(1,_TURNTABLE);
                colLines.get(2).set(2,_TURNTABLE);
            }

        }else {
            //屏蔽两个转盘
            do {
                colLines = ((KbwsjXml)rollerXml).getColLine(path, rollerID,row,col);
            }while (colLines.stream().mapToLong(l -> l.stream().filter(i -> _TURNTABLE == i).count()>2?1:0).sum()>1);
        }

        //特殊免费
        if (free && ((KbwsjPlayMsgs)res).freeNum<8 &&((KbwsjPlayMsgs)res).freeType==1){

            if ( point >1 && ((KbwsjPlayMsgs)res).task[point][2]==1 ){
                //50个wild
                ArrayList<Integer> col = colLines.get(RandomUtil.randomInt(5));
                for (int i = 0; i < row; i++) {
                    col.set(i,_WILD);
                }
                for (int i = row; i < col.size(); i++) {
                    col.set(i,-1);
                }
            }

            if (point >3 && ((KbwsjPlayMsgs)res).task[point][3]==1){
                //50个_COIN
                int anInt = RandomUtil.randomInt(5);
                for (int i = 0; i < colLines.size(); i++) {
                    ArrayList<Integer> col = colLines.get(i);
                    for (int j = 0; j < row*2; j++) {
                        if (anInt==i){
                            col.add(0,RandomUtil.randomInt(_COIN,_COIN+4));
                        }else {
                            col.add(-1);
                        }
                    }

                }
            }
        }

        ArrayList<int[]> allSlots = iconDown(colLines);

        return allSlots;
    }

    public static void main(String[] args) throws Exception{
        KbwsjIli.getInstance().init();
        KbwsjRoom room = new KbwsjRoom();
        room.init(1,KbwsjXml.getInstance(),false,1000,2);
        room.roundPlay();
        GameUtil.print(room.endSlots);
        System.out.println(room.res);

    }
}
